﻿using System;
using System.Collections.Generic;
using System.Text;

namespace TCCHWLib.Commands
{
    public class AllocateCommand:ICommand
    {
        /// <summary>
        /// </summary>
        /// <param name="parameter1">name of the parameter</param>
        /// <param name="parameter2">Size of the Parameter</param>
        /// <param name="paramterType1">type is value</param>
        /// <param name="parameterType2">type is value</param>
        public AllocateCommand(object parameter1, ParameterType paramterType1, object parameter2, ParameterType parameterType2)
        {
            m_Operand1 = parameter1;
            m_Operand2 = parameter2;
            m_Type2 = parameterType2;
            m_Type1 = paramterType1;
            m_ExOperand1 = parameter1;
            m_ExOperand2 = parameter2;
            m_ExType1 = paramterType1;
            m_ExType2 = parameterType2;
        }
        public override object Execute(Processor processor)
        {
            
            int size = 0;
            try
            {
                size = Convert.ToInt32(m_ExOperand2);
            }
            catch (Exception)
            {
                throw;
            }
            m_Value = processor.Cache.Allocate(size);
            lock (Processor.GlobalLiteralTable)
            {
                if (!Processor.GlobalLiteralTable.ContainsKey(Convert.ToString(m_ExOperand1)))
                    Processor.GlobalLiteralTable.Add(Convert.ToString(m_ExOperand1), new LiteralTable(Convert.ToInt32(m_Value), size));
            }
            return m_Value;
        }
        public override void Undo(Processor processor)
        {
            if (m_Value == null)
                return;
            int address = Convert.ToInt32(m_Value);
            int size = 1;
            string key = null;
            foreach (string x in Processor.GlobalLiteralTable.Keys)
            {
                if (Processor.GlobalLiteralTable[x].Address == address)
                {
                    key = x;
                    size = Processor.GlobalLiteralTable[x].Size;
                }
            }
            if (key == null)
                return;
            processor.Cache.Deallocate(address,size);
            Processor.GlobalLiteralTable.Remove(key);
        }

        public override void ExecuteGlobal(Processor processor)
        {
           
            int size = 0;
            try
            {
                size = Convert.ToInt32(m_ExOperand2);
            }
            catch (Exception)
            {
                throw;
            }
            m_Value = processor.Cache.Allocate(size);
            if (!Processor.GlobalLiteralTable.ContainsKey(Convert.ToString(m_ExOperand1)))
                Processor.GlobalLiteralTable.Add(Convert.ToString(m_ExOperand1), new LiteralTable(Convert.ToInt32(m_Value), size));
        }
        public override string ToString()
        {
            return String.Format("ALLOC ( {0} , size({1}) )", m_Operand1, m_Operand2);
        }
    }
}
